package com.vinfai.thread.concurrent;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * CyclicBarrier 允许一组线程相互等待，直到达到某个公共屏障点(common barrier point)
 * 所谓屏障点就是一组任务执行完毕的时刻
 * @author vinfai
 * 应该场景：
 * 有四个游戏玩家玩游戏，游戏有三个关卡，每个关卡必须要所有玩家都到达后才能允许通关。 
其 实这个场景里的玩家中如果有玩家A先到了关卡1，他必须等待其他所有玩家都到达关卡1时才能通过
，也就是说线程之间需要互相等待，这和 CountDownLatch的应用场景有区别，
CountDownLatch里的线程是到了运行的目标后继续干自己的其他事情，
而这里的线程需要等待其 他线程后才能继续完成下面的工作。 
 同countDownLatch的区别是cyclicBarrier是多次的.
 */
public class CyclicBarrierTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		BarrierAction action = new BarrierAction();
		CyclicBarrier cyclicBarrier = new CyclicBarrier(5, action);
		for(int i=0;i<10;i++){
			new Thread(new Player(i,cyclicBarrier)).start();
		}
	}
}
/**
 * 当一组线程都处于等待(直到达到某个公共屏障点)，执行的action
 */
class BarrierAction implements Runnable{
	@Override
	public void run(){
		System.out.println("THE GROUP IS OVER NOW....");
	}
}
class Player implements Runnable{

	private CyclicBarrier cyclicBarrier;
	//线程组中第几个
	private int index;
	
	public Player(int index,CyclicBarrier cyclicBarrier){
		this.index = index;
		this.cyclicBarrier = cyclicBarrier;
	}
	
	@Override
	public void run() {
		System.out.println("PLAYER "+index+" IS WAITING TO LEVEL 2.");
		try {
			cyclicBarrier.await();//等待一组线程都到达
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			e.printStackTrace();
		}
		System.out.println("PLAYER "+index+" IS IN LEVEL 2.");
	}
}
